package com.bajiao.common.util;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Description: 日期格式转换工具类
 * @Author: GuoYu
 * @Date: 2024-10-10/7/2
 * @Version: V1.0
 */
public class DateUtil {
    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";

    public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";

    public static final String DEFAULT_DATETIME_FORMAT = "yyyy-MM-dd HH:mm";

    public static final String DEFAULT_DATETIME_FORMAT_SEC = "yyyy-MM-dd HH:mm:ss";

    public static final String DEFAULT_DATE_FORMAT_YYYYMMDDHH = "yyyyMMddHH";

    /**
     * 年月日格式
     */
    public static final String YEARMONTHDAY_FORMAT = "yyyyMMdd";

    public static final String HOURMINSEC_FORMAT = "HHmmss";

    /**
     * 年月日格式
     */
    public static final String YEAR_DATETIME_FORMAT = "yyyy年MM月dd日";

    /**
     * 缺省短日期格式
     */
    public final static String DEFAULT_SHORT_DATE_FORMAT = "yyyy-MM-dd";

    public final static String DEFAULT_SHORT_TIME_FORMAT = DEFAULT_SHORT_DATE_FORMAT + " " + DEFAULT_TIME_FORMAT;

    public static Date today() {
        return formatDate(new Date(), DEFAULT_DATE_FORMAT);
    }

    public static String now() {
        return dateToString(new Date(), DEFAULT_DATETIME_FORMAT_SEC);
    }

    public static Date formatDate(Date date, String formatStr) {
        Date ret = null;
        SimpleDateFormat formatter = new SimpleDateFormat(formatStr);
        String dateStr = formatter.format(date);
        try {
            ret = formatter.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return ret;
    }

    /**
     * @param date
     * @param format
     * @return
     */
    public static String dateToString(Date date, String format) {
        String ret = "";
        if (date == null) {
            return ret;
        }
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        ret = formatter.format(date);
        return ret;
    }

    public static Date convertStrToDate(String time, String dateFormat) {
        DateTimeFormatter format = DateTimeFormat.forPattern(dateFormat);
        //时间解析
        DateTime dt1 = DateTime.parse(time, format);
        return dt1.toDate();
    }

    /**
     * str日期类型转DATE
     *
     * @param dateStr
     * @return Date
     */
    public static Date strToDate(String dateStr) {
        if (dateStr == null || "".equals(dateStr.trim())) {
            return null;
        }
        try {
            return strToDate(dateStr, DEFAULT_DATE_FORMAT);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @param dateStr
     * @param format
     * @return Date
     */
    public static Date strToDate(String dateStr, String format) {
        Date ret = null;
        try {
            SimpleDateFormat formatter = new SimpleDateFormat(format);
            ret = formatter.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return ret;
    }

    /**
     * @param date
     * @param day
     * @return
     */
    public static Date addDays(Date date, int day) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.DATE, day);
        Date newDate = c.getTime();
        return newDate;
    }

    /**
     * @param date
     * @param day
     * @return
     */
    public static Date subDays(Date date, int day) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.DATE, c.get(Calendar.DATE) - day);
        Date newDate = c.getTime();
        return newDate;
    }

    /**
     * 日期加几个月
     *
     * @param date  输入的日期
     * @param month 要加几个月
     * @return
     */
    public static Date addMonths(Date date, int month) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MONTH, month);
        Date newDate = c.getTime();
        return newDate;
    }

    /**
     * 日期加几年
     *
     * @param date 日期
     * @param year 要加几年
     * @return
     */
    public static Date addYears(Date date, int year) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.YEAR, year);
        Date newDate = c.getTime();
        return newDate;
    }

    /**
     * @param date
     * @param ss
     * @return
     */
    public static Date addss(Date date, int ss) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.SECOND, ss);
        Date newDate = c.getTime();
        return newDate;
    }

    public static Date addMinute(Date date, int minute) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MINUTE, minute);
        Date newDate = c.getTime();
        return newDate;
    }

    public static int getNowHourOfDay() {
        Calendar c = Calendar.getInstance();
        return c.get(Calendar.HOUR_OF_DAY);
    }

    public static int getNowDayOfMonth() {
        return getDaysOfMonth(new Date());
    }

    public static int getDayOfMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.MONTH) + 1;
    }

    public static int getDayOfYear(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.YEAR);
    }

    /**
     * @return
     */
    public static int getNowMonth() {
        Calendar c = Calendar.getInstance();
        return c.get(Calendar.MONTH) + 1;
    }

    /**
     * @return
     */
    public static int getNowYear() {
        Calendar c = Calendar.getInstance();
        return c.get(Calendar.YEAR);
    }

    /**
     * yyyy-MM-dd HH-mm
     *
     * @param beginDate
     * @return
     */
    public static String getSimpleTime(Date beginDate) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        return format.format(beginDate);
    }

    /**
     * @return
     */
    public static String getTimeBegin(int day, Date nowDate) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        //创建Calendar对象
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(nowDate);
        calendar.add(Calendar.DATE, day);
        //返回当天的开始时间
        String result = format.format(calendar.getTime());
        return result;
    }

    /**
     * @return
     */
    public static String getTimeEnd(int day, Date nowDate) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
        //创建Calendar对象
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(nowDate);
        calendar.add(Calendar.DATE, day);
        //返回当天的最后时间
        String result = format.format(calendar.getTime());
        return result;
    }

    public static int getDaysOfMonth(Date now) {
        Calendar calender = Calendar.getInstance();
        calender.setTime(now);
        return calender.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

    public static Date getMonth(int differ) {
        Calendar date = Calendar.getInstance();
        date.add(Calendar.MONTH, differ);
        Date result = DateUtil.formatDate(date.getTime(), "yyyy-MM-dd");
        return result;
    }

    public static Date getYear(int differ) {
        Calendar date = Calendar.getInstance();
        date.add(Calendar.YEAR, differ);
        Date result = DateUtil.formatDate(date.getTime(), "yyyy-MM-dd HH:mm:ss");
        return result;
    }

    public static Date integerToDate(Integer time) {
        if (time == null) {
            return null;
        }
        long longTime = ((long) time) * 1000;
        return new Date(longTime);
    }

    public static int getMonthNum(Date start, Date end) {
        Date index = start;
        int count = 0;
        while (true) {
            if (DateUtil.addMonths(index, 1).compareTo(DateUtil.addDays(end, 1)) < 0) {
                index = DateUtil.addMonths(index, 1);
                count++;
            } else {
                break;
            }
        }
        return count;
    }

    public static String addDate(String date, int days) {
        if (Long.parseLong(date) < 19010101) {
            return date;
        }
        String str = date;
        int year = Integer.parseInt(str.substring(0, 4));
        int month = Integer.parseInt(str.substring(4, 6));
        int day = Integer.parseInt(str.substring(6, 8));
        GregorianCalendar calendar = new GregorianCalendar(year, month - 1, day);
        calendar.add(Calendar.DATE, days);
        long newDate = calendar.get(Calendar.YEAR) * 10000 + (calendar.get(Calendar.MONTH) + 1) * 100 + calendar.get(Calendar.DAY_OF_MONTH);
        return "" + newDate;
    }

    /**
     * 时间戳yyyyMMddHHmmss
     */
    public static String getTimeStamp() {
        return dateToString(new Date(), "yyyyMMddHHmmss");
    }

    /**
     * 时间戳yyyyMMdd
     */
    public static String getTimeStampYmd() {
        return dateToString(new Date(), "yyyyMMdd");
    }

    /**
     * 根据时间获取年月日
     *
     * @param d1
     * @return
     */
    public static String getTimeStampYmd(Date d1) {
        return dateToString(d1, "yyyyMMdd");
    }

    /**
     * 时间戳yyyyMMddHHmmssSSS
     */
    public static String getTimeStampYmdhms() {
        return dateToString(new Date(), "yyyyMMddHHmmssSSS");
    }

    /**
     * 时间戳HHmmssSSS
     */
    public static String getTimeStampHms() {
        return dateToString(new Date(), "HHmmssSSS");
    }

    /**
     * 是否为一年的最后一天
     *
     * @param date
     * @param format
     * @return
     * @throws ParseException
     * @author FanJq 2024-10-10
     */
    public static boolean isYearEnd(String date, String format) throws ParseException {
        DateFormat df = new SimpleDateFormat(format);
        Calendar localCalendar = Calendar.getInstance();
        try {
            localCalendar.setTime(df.parse(date));
        } catch (ParseException e) {
            throw e;
        }
        int month = localCalendar.get(Calendar.MONTH) + 1;
        int day = localCalendar.get(Calendar.DAY_OF_MONTH);
        if (month == 12 && day == 31) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 是否为一个月的最后一天
     *
     * @param date
     * @param format
     * @return
     * @throws ParseException
     * @author FanJq 2024-10-10
     */
    public static boolean isMonthEnd(String date, String format) throws ParseException {
        DateFormat df = new SimpleDateFormat(format);
        Calendar localCalendar = Calendar.getInstance();
        try {
            localCalendar.setTime(df.parse(date));
        } catch (ParseException e) {
            throw e;
        }
        int month = localCalendar.get(Calendar.MONTH);
        localCalendar.add(Calendar.DAY_OF_MONTH, 1);
        int month2 = localCalendar.get(Calendar.MONTH);
        if (month != month2) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 获取昨天
     *
     * @return
     * @author FanJq 2024-10-10
     */
    public static Date getYesterDay(Date today) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(today);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) - 1);
        return calendar.getTime();
    }

    public static String getYesterDay(Date today, String format) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(today);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) - 1);
        DateFormat df = new SimpleDateFormat(format);
        return df.format(calendar.getTime());
    }

    /**
     * 计算两个日期之间相差的天数
     *
     * @param startDate 较小的时间
     * @param endDate   较大的时间
     * @return
     */
    public static int daysBetween(Date startDate, Date endDate) {
        startDate = formatDate(startDate, DEFAULT_DATE_FORMAT);//只取年月日
        endDate = formatDate(endDate, DEFAULT_DATE_FORMAT);//只取年月日
        if (startDate.compareTo(endDate) > 0) {
            return -1;
        }
        long start = startDate.getTime() / (1000 * 60 * 60 * 24);
        long end = endDate.getTime() / (1000 * 60 * 60 * 24);
        return (int) (end - start);
    }

    /**
     * 计算两个日期之间相差的天数
     *
     * @param startDate 较小的时间
     * @param endDate   较大的时间
     * @return
     */
    public static int monthsBetween(String startDate, String endDate) {
        if (startDate.compareTo(endDate) > 0) {
            return -1;
        }
        int result = 0;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        try {
            c1.setTime(sdf.parse(startDate));
            c2.setTime(sdf.parse(endDate));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        int years = c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR);
        result = c2.get(Calendar.MONTH) + 12 * years - c1.get(Calendar.MONTH);
        return result == 0 ? 1 : Math.abs(result);
    }

    /**
     * 计算两个日期之间相差的天数
     *
     * @param startDate 较小的时间
     * @param endDate   较大的时间
     * @return
     */
    public static int monthsBetween(Date startDate, Date endDate) {
        if (startDate.compareTo(endDate) > 0) {
            return -1;
        }
        int result = 0;
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(startDate);
        c2.setTime(endDate);
        int years = c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR);
        result = c2.get(Calendar.MONTH) + 12 * years - c1.get(Calendar.MONTH);
        return result == 0 ? 1 : Math.abs(result);
    }

    /**
     * 比较两个时间是否相等之比较前8位
     *
     * @param d1
     * @param d2
     * @return
     */
    public static boolean compareDate(Date d1, Date d2) {
        return dateToString(d1, YEARMONTHDAY_FORMAT).equals(dateToString(d2, YEARMONTHDAY_FORMAT));
    }

    /**
     * 判断当前时间是否在某个时间段之间
     *
     * @throws ParseException
     */
    public static boolean timeBetween(String startTime, String endTime) {
        DateFormat sdf = new SimpleDateFormat("HH:mm");
        long start = 0;
        long end = 0;
        long now = 0;
        try {
            start = sdf.parse(startTime).getTime();
            end = sdf.parse(endTime).getTime();
            String str = sdf.format(new Date());
            now = sdf.parse(str).getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        if (now > end || now < start) {
            return false;
        }
        return true;
    }

    /**
     * 根据时间获取年月日yyyy-MM-dd
     *
     * @param d1
     * @return
     */
    public static String getYmd(Date d1) {
        return dateToString(d1, "yyyy-MM-dd");
    }

    public static void main(String[] args) {
        System.out.println(monthsBetween("2017-07-18","2017-07-19"));
    }

    public static String getGTM(Date date) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE d MMM yyyy HH:mm:ss 'GMT'", Locale.US);
        simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
        return simpleDateFormat.format(date);
    }
}
